package com.qsign.sfrz_android.utils;

import android.content.Context;
import android.security.KeyPairGeneratorSpec;
import android.security.keystore.KeyProperties;
import android.util.Base64;

import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableEntryException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Calendar;
import java.security.cert.CertificateException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.security.auth.x500.X500Principal;

/**
 * Created by wgy on 2019/8/28.
 */

public class KeyStoreAddValid {
    private static final String RSA_MODE_OAEP = "RSA/ECB/PKCS1Padding";
    private static KeyPair createKeyPair(String alias, Context context) {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties
                    .KEY_ALGORITHM_RSA, "AndroidKeyStore");

            Calendar start = Calendar.getInstance();
            Calendar end = Calendar.getInstance();
            end.add(Calendar.YEAR, 30);
            AlgorithmParameterSpec spec;
            spec = new KeyPairGeneratorSpec.Builder(context)
                    //使用别名来检索的关键。这是一个关键的关键!
                    .setAlias(alias)
                    // 用于生成自签名证书的主题 X500Principal 接受 RFC 1779/2253的专有名词
                    .setSubject(new X500Principal("CN=" + alias))
                    //用于自签名证书的序列号生成的一对。
                    .setSerialNumber(BigInteger.TEN)
                    // 签名在有效日期范围内
                    .setStartDate(start.getTime())
                    .setEndDate(end.getTime())
                    .build();
            keyPairGenerator.initialize(spec);
            return keyPairGenerator.generateKeyPair();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 进行RSA加密
     * @param plainText 被加密数据
     * @return
     * @throws Exception
     */
    public static String encryptRSA(Context context,String plainText,String alias) throws Exception {
        PublicKey key = null;
        try {
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            if (keyStore != null && keyStore.containsAlias(alias)) {
                key = keyStore.getCertificate(alias).getPublicKey();
            }else{
                key = createKeyPair(alias,context).getPublic();
            }
            Cipher cipher = Cipher.getInstance(RSA_MODE_OAEP);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encryptedByte = cipher.doFinal(plainText.getBytes("UTF-8"));
            return Base64.encodeToString(encryptedByte, Base64.NO_WRAP);
        }catch (CertificateException e) {
            e.printStackTrace();
            return null;
        }catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
        catch (IOException e) {
            e.printStackTrace();
            return null;
        } catch (KeyStoreException e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     *
     * @param alias Rsa别名
     * @param enseed 加密的种子
     * @return 解密数据
     */
    public static String deSeed(String alias, String enseed) {
        KeyStore.PrivateKeyEntry privateKeyEntry = null;
        try {
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            Cipher cipher = Cipher.getInstance(RSA_MODE_OAEP);
            privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore
                    .getEntry(alias, null);
            PrivateKey privateKey = privateKeyEntry.getPrivateKey();
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] encryptedByte = Base64.decode(enseed, Base64.NO_WRAP);
            return new String(cipher.doFinal(encryptedByte));
        }catch (CertificateException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnrecoverableEntryException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }

        return enseed;
    }


}
